﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Brain
{
    public class ServiceManager : IServiceProvider
    {
        /// <summary>
        /// All Services currently loaded
        /// </summary>
        protected Dictionary<Type, object> services = new Dictionary<Type, object>();

        public ServiceManager(IGraphicsDeviceService service)
        {
            AddService(typeof(IGraphicsDeviceService), service);
        }

        /// <summary>
        /// Adds a new Service
        /// </summary>
        /// <param name="Service"></param>
        /// <param name="Provider"></param>
        public void AddService(Type Service, object Provider)
        {
            if (services.ContainsKey(Service))
            {
                //Engine.ExceptionManager.HandleException("WARNING #5 - The Service Manager already contains a Service of type " + Service.Name,
                  //  ExceptionType.Warning);
                return;
            }


            this.services.Add(Service, Provider);
        }

        /// <summary>
        /// Removes all the Services
        /// </summary>
        public void Clear()
        {
            List<Type> toRemove = new List<Type>();

            foreach (KeyValuePair<Type, object> service in services)
                toRemove.Add(service.Key);

            foreach (Type type in toRemove)
#if !SILVERLIGHT
                if (type != typeof(IGraphicsDeviceService))
#endif
                    services.Remove(type);
        }

        /// <summary>
        /// Verifies if the Object is a Service
        /// </summary>
        /// <param name="Object"></param>
        /// <param name="ServiceType"></param>
        /// <returns></returns>
        public bool IsService(object Object, out Type ServiceType)
        {
            if (services.ContainsValue(Object))
            {
                foreach (KeyValuePair<Type, object> service in services)
                    if (service.Value == Object)
                    {
                        ServiceType = service.Key;
                        return true;
                    }
            }

            ServiceType = null;
            return false;
        }

        /// <summary>
        /// Gets a Service by it's type
        /// </summary>
        /// <param name="Service"></param>
        /// <returns></returns>
        public object GetService(Type Service)
        {
            foreach (Type type in services.Keys)
                if (type == Service)
                    return services[type];

            //Engine.ExceptionManager.HandleException(
              //"WARNING #6 - The Service Manager doesn't contains a Service of type " + Service.Name, ExceptionType.Warning);
            return null;
        }

        /// <summary>
        /// Pega um serviço
        /// </summary>
        /// <typeparam name="T">O Tipo do serviço</typeparam>
        /// <returns>O serviço desejado</returns>
        public T GetService<T>()
        {
            object result = GetService(typeof(T));

            if (result != null)
                return (T)result;

            return default(T);
        }

        /// <summary>
        /// Remove um serviço
        /// </summary>
        /// <param name="Service">O Tipo do serviço para remover</param>
        public void RemoveService(Type Service)
        {
            if (services.ContainsKey(Service))
                services.Remove(Service);
        }

        /// <summary>
        /// Se contem um serviço
        /// </summary>
        /// <param name="Service">Tipo de serviço</param>
        /// <returns></returns>
        public bool ContainsService(Type Service)
        {
            return services.ContainsKey(Service);
        }
    }
}